import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'lib_cloud_storage_platform_interface.dart';

/// An implementation of [LibCloudStoragePlatform] that uses method channels.
class MethodChannelLibCloudStorage extends LibCloudStoragePlatform {
  /// The method channel used to interact with the native platform.
  @visibleForTesting
  final methodChannel = const MethodChannel('lib_cloud_storage');

  @override
  Future<String?> getPlatformVersion() async {
    final version =
        await methodChannel.invokeMethod<String>('getPlatformVersion');
    return version;
  }

  static const String method_upload_to_google_cloud =
      "uploadToGoogleCloud"; //谷歌云盘
  static const String method_google_login_sign = "google_login_sign"; // 谷歌登录
  static const String method_google_download = "google_drive_download"; //谷歌云盘下载
  static const String method_google_file_list =
      "google_drive_file_list"; //谷歌云盘中文件列表

  @override
  Future<GoogleLoginResult> startGoogleLogin({String? clientID}) async {
    try {
      var json = null;
      if (clientID != null && Platform.isIOS) {
        Map<String, dynamic> map = {"clientID": clientID};
        json = jsonEncode(map);
      }
      var result = await methodChannel.invokeMethod<String>(
          method_google_login_sign, json);
      Map<String, dynamic> result_json = jsonDecode(result!);
      int code = result_json["code"];
      if (code == 0) {
        String email = result_json["email"];
        String idToken = result_json["idToken"];

        if (Platform.isIOS) {
          return GoogleLoginResult(email, idToken,
              expirationDate: result_json["expirationDate"]);
        } else {
          return GoogleLoginResult(email, idToken);
        }
      } else {
        int code = result_json["code"];
        String error = result_json["error"];
        return Future.error(Exception((code, error)));
      }
    } catch (e) {
      return Future.error(Exception((-1, e.toString())));
    }
  }

  @override
  Future<FileList> fetchGoogleDriveFileList(String email, String prefix) async {
    try {
      Map<String, dynamic> map = {"prefix": prefix, "email": email};
      var json = jsonEncode(map);
      var result = await methodChannel.invokeMethod<String>(
          method_google_file_list, json);
      Map<String, dynamic> result_json = jsonDecode(result!);
      int code = result_json["code"];
      if (code == 0) {
        var jsonArray = result_json["fileList"] as List<dynamic>;
        List<GoogleDriveFile> dataList = jsonArray.map((e) {
          return GoogleDriveFile(e["fileId"], e["fileName"]);
        }).toList();
        return FileList(dataList);
      } else {
        var error = result_json["error"];
        return Future.error(Exception(error));
      }
    } catch (e) {
      return Future.error(e);
    }
  }

  @override
  Future<String> fetchGoogleDriveFileById(String email, String fileId) async {
    try {
      Map<String, dynamic> map = {"fileId": fileId, "email": email};
      var json = jsonEncode(map);
      var result = await methodChannel.invokeMethod<String>(
          method_google_download, json);
      Map<String, dynamic> result_json = jsonDecode(result!);
      int code = result_json["code"];
      if (code == 0) {
        return result_json["fileContent"]; // 返回文件内容
      } else {
        var error = result_json["error"];
        return Future.error(Exception(error));
      }
    } catch (e) {
      return Future.error(e);
    }
  }

  @override
  Future<String> uploadToGoogleCloud(
      String email, String fileName, String fileContent) async {
    try {
      Map<String, dynamic> map = {
        "fileName": fileName,
        "fileContent": fileContent,
        "email": email
      };
      var json = jsonEncode(map);
      var result = await methodChannel.invokeMethod<String>(
          method_upload_to_google_cloud, json);
      Map<String, dynamic> result_json = jsonDecode(result!);
      int code = result_json["code"];
      if (code == 0) {
        return result_json["fileId"]; // 返回文件fileId
      } else {
        var error = result_json["error"];
        return Future.error(Exception(error));
      }
    } catch (e) {
      return Future.error(e);
    }
  }
}
